Management Consoleの権限不足エラーをデコードする
こんにちは。望月です。
今日はヒジョーに縁の下の力持ち的なサービス、STSについてです。
権限不足のエラーメッセージ
IAM userを利用して利用できる権限を制御している場合、Management Consoleで許可されていない操作を実行しようとした場合にエラーになることがあります。 *1たとえばReadOnlyのPermissionを与えられているユーザがEC2をTerminateしようとした時などですね。Management Consoleですと、こういったエラーが表示されます。
画面だとエラーメッセージが見づらいですが、なにかエンコードされた文字列が並んでいるのが確認できると思います。AWS CLIからだとこういった出力があります。
$ aws ec2 terminate-instances --profile no-permission-user --instance-id i-xxxxxxxx A client error (UnauthorizedOperation) occurred when calling the TerminateInstances operation: You are not authorized to perform this operation. Encoded authorization failure message: tbPtNRmz55vw........(後略)
さて、このエンコードされた文字列ですが、どうやってデコードすればいいのでしょうか?答えはAWS STSにAPIが用意されていますので、それを利用しましょう。
DecodeAuthorizationMessage
STSのDecodeAuthorizationMessage APIを利用すると、上記のエラー文字列をデコードすることが出来ます。APIの仕様やデータ構造などについては公式ドキュメントを参照して下さい。試しにAWS CLIでデコードしてみましょう。
ちなみに、デコードの時に使うアクセスキーは、エラーメッセージを取得するアクションを行ったアクセスキーと同じでなければいけません。
さらに、sts:DecodeAuthorizationMessageが許可されていないと処理が実行できないため、権限が足りない場合は明示的に権限を与えてあげましょう。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:DecodeAuthorizationMessage", "Resource": "*" } ] }
実行結果は以下のようになります。エンコードされた文字列が長いので、今回は文字列をerror.txtに保存してfile://で呼び出しています。
$ aws sts decode-authorization-message --encoded-message file://error.txt --profile no-permission-user { "DecodedMessage": "{\"allowed\":false,\"explicitDeny\":false,\"matchedStatements\":{\"items\":[]},\"failures\":{\"items\":[]},\"context\":{\"principal\":{\"id\":\"xxxxxxxxxxxxxxxxxxxxx\",\"name\":\"no-permission\",\"arn\":\"arn:aws:iam::019930502935:user/no-permission\"},\"action\":\"ec2:TerminateInstances\",\"resource\":\"arn:aws:ec2:ap-northeast-1:xxxxxxxxxxxxx:instance/i-xxxxxxxx\",\"conditions\":{\"items\":[{\"key\":\"ec2:Tenancy\",\"values\":{\"items\":[{\"value\":\"default\"}]}},{\"key\":\"ec2:RootDeviceType\",\"values\":{\"items\":[{\"value\":\"ebs\"}]}},{\"key\":\"ec2:ebsOptimized\",\"values\":{\"items\":[{\"value\":\"false\"}]}},{\"key\":\"ec2:InstanceType\",\"values\":{\"items\":[{\"value\":\"t1.micro\"}]}},{\"key\":\"ec2:Region\",\"values\":{\"items\":[{\"value\":\"ap-northeast-1\"}]}},{\"key\":\"ec2:ResourceTag/Name\",\"values\":{\"items\":[{\"value\":\"\"}]}},{\"key\":\"ec2:AvailabilityZone\",\"values\":{\"items\":[{\"value\":\"ap-northeast-1c\"}]}}]}}}" }
だいぶ見づらいですが、デコードされていることは確認できました。あとはjqに食べさせてあげましょう。
今回は試しにどのアクションを行った時のエラーなのかを取得してみます。
$ aws sts decode-authorization-message --encoded-message file://error.txt --profile no-permission-user \ | jq -r '.DecodedMessage' \ | jq -c '.context.action' "ec2:TerminateInstances"
TerminateInstancesを行った際のエラーメッセージであることが取得できました。Actionの他にもユーザのARNなど、様々な情報が取得できるので、権限周りでのManagement Consoleでのエラーに対するデバッグ用途に使えそうですね。
脚注
- 手元で確認した限り、ここで紹介したエラー文字列を返すAPIと返さないAPIがあるようです。どういった理由でその違いがあるかはわかりませんでした。どなたか知っていたら教えて下さい。 ↩